package com.cencat.framework.security.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 登录用户信息
 */
@Data
public class LoginUser implements UserDetails {
    
    private static final long serialVersionUID = 1L;
    
    /**
     * 用户ID
     */
    private Long userId;
    
    /**
     * 用户名
     */
    private String username;
    
    /**
     * 密码
     */
    private String password;
    
    /**
     * 租户ID
     */
    private Long tenantId;
    
    /**
     * 真实姓名
     */
    private String realName;
    
    /**
     * 邮箱
     */
    private String email;
    
    /**
     * 手机号
     */
    private String phone;
    
    /**
     * 头像
     */
    private String avatar;
    
    /**
     * 用户状态
     */
    private Integer status;
    
    /**
     * 权限集合
     */
    private Set<String> permissions;
    
    /**
     * 角色集合
     */
    private Set<String> roles;
    
    /**
     * 是否超级管理员
     */
    private Boolean isSuperAdmin;
    
    /**
     * 是否租户管理员
     */
    private Boolean isTenantAdmin;
    
    /**
     * 部门ID
     */
    private Long deptId;
    
    /**
     * 岗位ID
     */
    private Long positionId;
    
    /**
     * 登录IP
     */
    private String loginIp;
    
    /**
     * 登录时间
     */
    private Long loginTime;
    
    /**
     * 过期时间
     */
    private Long expireTime;
    
    /**
     * Token令牌
     */
    private String token;
    
    /**
     * 获取权限列表
     */
    @JsonIgnore
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return permissions.stream()
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toSet());
    }
    
    /**
     * 账户是否未过期
     */
    @JsonIgnore
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    
    /**
     * 账户是否未锁定
     */
    @JsonIgnore
    @Override
    public boolean isAccountNonLocked() {
        return status != null && status == 1;
    }
    
    /**
     * 凭证是否未过期
     */
    @JsonIgnore
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    
    /**
     * 账户是否启用
     */
    @JsonIgnore
    @Override
    public boolean isEnabled() {
        return status != null && status == 1;
    }
    
    /**
     * 获取权限字符串集合
     */
    public Set<String> getPermissions() {
        return permissions;
    }
    
    /**
     * 设置权限字符串集合
     */
    public void setPermissions(Set<String> permissions) {
        this.permissions = permissions;
    }
    
    /**
     * 添加权限
     */
    public void addPermission(String permission) {
        this.permissions.add(permission);
    }
    
    /**
     * 移除权限
     */
    public void removePermission(String permission) {
        this.permissions.remove(permission);
    }
    
    /**
     * 检查是否拥有指定权限
     */
    public boolean hasPermission(String permission) {
        return permissions != null && permissions.contains(permission);
    }
    
    /**
     * 检查是否拥有任一权限
     */
    public boolean hasAnyPermission(String... permissions) {
        if (this.permissions == null) {
            return false;
        }
        for (String permission : permissions) {
            if (this.permissions.contains(permission)) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 检查是否拥有所有权限
     */
    public boolean hasAllPermissions(String... permissions) {
        if (this.permissions == null) {
            return false;
        }
        for (String permission : permissions) {
            if (!this.permissions.contains(permission)) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * 设置Token令牌
     */
    public void setToken(String token) {
        this.token = token;
    }
}